﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Newtonsoft.Json;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web.Http;

using mshtml;
using System.Windows.Forms;
using System.Windows;
using System.Drawing;
using System.Threading;

namespace Coevery.Tasacion.Services
{

    public class TasacionDataHelper
    {
        public static JsonData buscarInmueblesProximos
           (string lat,         // latitude
            string lon,         // longitude
            string tipovivienda) // tipovivienda
        {
            string operation_1 = "sale"; // sale or rent
            string flat_8 = "";          // Piso
            string penthouse_9 = ""; // Atico
            string studio_10 = "";   // Estudio
            string chalet_11 = "";   // Casa o Chalet
            string duplex_12 = "";   // Duplex
            string garage_13 = "";   // Garage
            string office_14 = "";   // Oficina
            string minRooms_15 = ""; // Minimo habitaciones

            switch (tipovivienda)
            {
                case "piso":
                    flat_8 = "true";
                    break;
                case "ático":
                    penthouse_9 = "true";
                    break;
                case "estudio":
                    studio_10 = "true";
                    break;
                case "chalet":
                    chalet_11 = "true";
                    break;
                case "dúplex":
                    duplex_12 = "true";
                    break;
                case "garaje":
                    garage_13 = "true";
                    break;
                case "oficina":
                    office_14 = "true";
                    break;
                default:
                    flat_8 = "true";
                    break;
            }

            return buscarInmueblesProximos(operation_1, lat, lon, null, null, null, null, flat_8, penthouse_9, studio_10, chalet_11, duplex_12, garage_13, office_14, minRooms_15, "1");
        }


        public static JsonData buscarInmueblesProximos
           (string operation_1, // sale or rent
            string lat,         // latitude
            string lon,         // longitude
            string minPrice_4,  // Precio minimo
            string maxPrice_5,  // Precio Maximo
            string minSize_6,   // Tamanio minimo
            string maxSize_7,   // Tamanio maximo
            string flat_8,      // Piso
            string penthouse_9, // Atico
            string studio_10,   // Estudio
            string chalet_11,   // Casa o Chalet
            string duplex_12,   // Duplex
            string garage_13,   // Garage
            string office_14,   // Oficina
            string minRooms_15, // Minimo habitaciones
            string pics_16)
        {    // Con fotos

            string k_0 = "f13d909975224dfcbc6ad2a867c78edb"; // HOME
            //string k_0 = "6d0fa8377ce1cbc7be2353863da55ebb"; // CGS      
            //string k_0 = "a144fb4b7eef6761583b4a9042d6ba65"; // MS      

            /* //BCKP
            double radio = Double.Parse(lat.Replace(".", ","));
            radio = radio + 0.0017;
            string center_2 = lat + "," + lon;
            string radio_3 = radio.ToString().Replace(",", ".") + "," + lon;
            */

            double latOrig = Math.Round(Double.Parse(lat.Replace(".", ",")), 4);
            double radio = Math.Round(latOrig, 4) + 0.0017;
            string center_2 = latOrig.ToString().Replace(",", ".") + "," + lon.ToString().Replace(",", ".");
            string radio_3 = radio.ToString().Replace(",", ".") + "," + lon.ToString().Replace(",", ".");

            // Valores por defecto de la busqueda
            operation_1 = (operation_1 == "" ? operation_1 = "sale" : operation_1); // Por defecto, ventas
            minPrice_4 = (minPrice_4 == "" ? minPrice_4 = "0" : minPrice_4);
            maxPrice_5 = (maxPrice_5 == "" ? maxPrice_5 = "99999999" : maxPrice_5);
            minSize_6 = (minSize_6 == "" ? minSize_6 = "0" : minSize_6);
            maxSize_7 = (maxSize_7 == "" ? maxSize_7 = "10000" : maxSize_7);
            flat_8 = (flat_8 == "" ? flat_8 = "false" : flat_8);
            penthouse_9 = (penthouse_9 == "" ? penthouse_9 = "false" : penthouse_9);
            studio_10 = (studio_10 == "" ? studio_10 = "false" : studio_10);
            chalet_11 = (chalet_11 == "" ? chalet_11 = "false" : chalet_11);
            duplex_12 = (duplex_12 == "" ? duplex_12 = "false" : duplex_12);
            garage_13 = (garage_13 == "" ? garage_13 = "false" : garage_13);
            office_14 = (office_14 == "" ? office_14 = "false" : office_14);
            minRooms_15 = (minRooms_15 == "" ? minRooms_15 = "1" : minRooms_15);

            if ((flat_8 == "false") && (penthouse_9 == "false") && (studio_10 == "false") && (chalet_11 == "false") &&
                (duplex_12 == "false") && (garage_13 == "false") && (office_14 == "false"))
            {
                flat_8 = "true";
            }
            string uri = "http://www.idealista.com/labs/propertyMap.htm?action=json&k={0}&operation={1}&center={2}&radio={3}&minPrice={4}" +
                          "&maxPrice={5}&minSize={6}&maxSize={7}&flat={8}&penthouse={9}&studio={10}&chalet={11}&duplex={12}&garage={13}" +
                          "&office={14}&minRooms={15}&pics={16}";


            string requestUri = string.Format(uri,
                HttpUtility.UrlEncode(k_0),
                HttpUtility.UrlEncode(operation_1),
                HttpUtility.UrlEncode(center_2),
                HttpUtility.UrlEncode(radio_3),
                HttpUtility.UrlEncode(minPrice_4),
                HttpUtility.UrlEncode(maxPrice_5),
                HttpUtility.UrlEncode(minSize_6),
                HttpUtility.UrlEncode(maxSize_7),
                HttpUtility.UrlEncode(flat_8),
                HttpUtility.UrlEncode(penthouse_9),
                HttpUtility.UrlEncode(studio_10),
                HttpUtility.UrlEncode(chalet_11),
                HttpUtility.UrlEncode(duplex_12),
                HttpUtility.UrlEncode(garage_13),
                HttpUtility.UrlEncode(office_14),
                HttpUtility.UrlEncode(minRooms_15),
                HttpUtility.UrlEncode(pics_16)
                );


            var response = _download_serialized_json_data<JsonData>(requestUri);
            return response;
        }


        private static T _download_serialized_json_data<T>(string url) where T : new()
        {
            T obj;
            using (var w = new WebClient())
            {
                //WARNING ESTO ES NUEVO: PARA QUE NO ME DEVUELVA VACIO EN CASO DE ERROR POR API KEY.
                //w.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2";
                var json_data = string.Empty;
                // attempt to download JSON data as a string
                try
                {
                    w.Encoding = System.Text.Encoding.UTF8;
                    json_data = w.DownloadString(url);

                }
                catch (Exception) { }

                //WARNING: MIENTRAS NO ME FACILITAN API KEY TIRO DE RESPUETA GUARDADA
                json_data = File.ReadAllText("C:\\Users\\carlos.montoya.plaza\\Desktop\\PFC\\3CoeveryMaster\\Coevery-master\\src\\Orchard.Web\\Modules\\Coevery.Tasacion\\SampleJsonResponse.txt");
                json_data = "{" + Regex.Match(json_data, @"\{([^)]*)\},").Groups[1].Value + "}";
                obj = JsonConvert.DeserializeObject<T>(json_data);

                return obj;
            }
        }

        public static string obtenerProperyCode(Element jsonData)
        {
            ///////////////////////////////////////////////////////////////////////////////////////////
            //                                                                                       //
            //                          G O O G L E   S E A R C H                                    //
            //                                                                                       //
            ///////////////////////////////////////////////////////////////////////////////////////////

            StringBuilder sb = new StringBuilder();
            // used on each read operation
            byte[] buf = new byte[8192];
            string GS = "http://google.com/search?q=idealista venta " + jsonData.munipality + " " + jsonData.address + " " +
                jsonData.neighborhood;
            // prepare the web page we will be asking for
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(GS);

            // execute the request
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            // we will read data via the response stream
            Stream resStream = response.GetResponseStream();
            string tempString = null;
            int count = 0;
            do
            {
                // fill the buffer with data
                count = resStream.Read(buf, 0, buf.Length);
                // make sure we read some data
                if (count != 0)
                {
                    // translate from bytes to ASCII text
                    tempString = Encoding.ASCII.GetString(buf, 0, count);

                    // continue building the string
                    sb.Append(tempString);
                }
            }
            while (count > 0);

            ///////////////////////////////////////////////////////////////////////////////////////////
            //                                                                                       //
            //                        I D E A L I S T A    P A R S I N G                             //
            //                                                                                       //
            ///////////////////////////////////////////////////////////////////////////////////////////

            //1. Buscar en tempString www.idealista.com/inmueble/   y aislar con regex la direccion que incluye el numero 27246112/
            string inmuebleCode = Regex.Match(sb.ToString(), @"\bidealista.com/inmueble/\b([^/]*)\/").Groups[1].Value;

            return inmuebleCode;

        }

        public static List<byte[]> obtenerFotos(string propertyCode)
        {
            try
            {

                StringBuilder sb = new StringBuilder();

                byte[] buf = new byte[8192];
                string GS = "http://idealista.com/inmueble/" + propertyCode;
                //string GS = url;
                // prepare the web page we will be asking for
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(GS);
                request.UnsafeAuthenticatedConnectionSharing = true;
                
                // execute the request
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                // we will read data via the response stream
                Stream resStream = response.GetResponseStream();
                string tempString = null;
                int count = 0;
                do
                {
                    // fill the buffer with data
                    count = resStream.Read(buf, 0, buf.Length);
                    // make sure we read some data
                    if (count != 0)
                    {
                        // translate from bytes to ASCII text
                        tempString = Encoding.ASCII.GetString(buf, 0, count);

                        // continue building the string
                        sb.Append(tempString);
                    }
                }
                while (count > 0);


                //2. Aislar con regex todas las fotos

                string input = sb.ToString();
                string start = "static/common/fotos/";
                string end = ".jpg";

                Regex r = new Regex(Regex.Escape(start) + "(.*?)" + Regex.Escape(end));
                MatchCollection matches = r.Matches(input);

                List<string> list = new List<string>();
                List<byte[]> imgList = new List<byte[]>();
                foreach (Match match in matches)
                {
                    list.Add("http://idealista.com/static/common/fotos/" + match.Groups[1].Value + ".jpg");
                }


                //3. Guardar las fotos
                WebClient wc = new WebClient();
                int i = 1;
                foreach (string foto in list)
                {
                    try
                    {
                        //wc.DownloadFile(foto, "C:\\foto"+i+".jpg");
                        byte[] img = wc.DownloadData(foto);
                        imgList.Add(img);
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine("WARNING");
                    }
                    i++;
                }
                return imgList;
            }
            catch (Exception e)
            {
                Debug.WriteLine("WARNING");
            }

            return new List<byte[]>();
        }

        public static void obtenerYGuardarFotos(string properyCode, string path)
        {
            //PRE: path tiene ya la estructura de carpetas creadas y vacía para desscargar las fotos
            runBrowserThread("http://www.idealista.com/inmueble/" + properyCode + "/", path);
        }

        private static void runBrowserThread(string url, string path)
        {
            var th = new Thread(() =>
            {
                var br = new WebBrowser();
                br.ScrollBarsEnabled = false;
                br.ScriptErrorsSuppressed = true;
                br.DocumentCompleted += browser_DocumentCompleted;
                br.Navigate(url);
                br.AutoScrollOffset=new Point(200, 10000);
                br.Update();
                br.Tag = path;
                Application.Run();

            });
            th.SetApartmentState(ApartmentState.STA);
            th.Start();
        }

        static void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            var br = sender as WebBrowser;
            br.Document.Body.ScrollIntoView(false);
            br.Navigated += (s1, e1) => { if (br.Document.Body != null) br.Document.Body.ScrollIntoView(false); };
            br.Navigate("javascript:window.scroll(0,document.body.scrollHeight);");
            Thread.Sleep(1000);

            string path = ((string)br.Tag);

            if (br.Url == e.Url)
            {
                //1. Html descargado
                IHTMLDocument2 doc = (IHTMLDocument2)br.Document.DomDocument;
                IHTMLControlRange imgRange = (IHTMLControlRange)((HTMLBody)doc.body).createControlRange();

                int i = 1;
                List<string> list = new List<string>();
                List<byte[]> imgList = new List<byte[]>();
                foreach (IHTMLImgElement img in doc.images)
                {
                    //2. Aislar con regex la URL de la foto

                    string input = ((mshtml.HTMLImg)(img)).outerHTML; //	"<img title=\"Imagen de Piso en barrio cuatro caminos\" alt=\"Imagen de Piso en barrio cuatro caminos\" src=\"http://st1.idealista.com/static/common/img/icons/px.png\" data-xiti-shared-n2=\"true\" data-xiti-page=\"detalle::foto\" data-orientation=\"vertical\" data-relative-position=\"7\" data-ondemand-img=\"http://img2.idealista.com/thumbs?wi=0&amp;he=600&amp;en=e2QOq%2B%2BzUcbn%2B%2FRVSTVyZVKbFhGqO9y0SlN0KMq1AQPSI5xRMiqhm2bb2hGlvyxOVaLMnt3SeF0kt8O3qFU4Zkhka2%2Fpsfom%2B8UtUtfStjVXAJjtrgu%2FAHvnPKZ9oEtLaCs3u0nPlX1cFSD6wLdDPH%2BkYQKfnxNAsuftAegGKdQ1mc3Qgp9%2Brts0FRL%2B3jfC&amp;ch=-1925023537\">"	string
                    string start = "data-ondemand-img=\"http://img2.idealista.com/thumbs?";
                    string end = "\">";

                    Regex r = new Regex(Regex.Escape(start) + "(.*?)" + Regex.Escape(end));
                    MatchCollection matches = r.Matches(input);
                     try
                    {
                        if (matches[0] != null)
                        {
                            string sufix = matches[0].Groups[1].Value;
                            sufix = sufix.Replace("&amp;", "&");

                            string completeUrl = "http://img2.idealista.com/thumbs?" + sufix;

                            list.Add(completeUrl);
                            Debug.WriteLine(completeUrl);
                        }
                    }
                     catch (Exception ex) { }
                }

                //3. Guardar las fotos
                WebClient wc = new WebClient();
                int k = 1;
                foreach (string foto in list)
                {
                    try
                    {
                        wc.DownloadFile(foto, path+"foto"+k+".jpg");
                        //byte[] img = wc.DownloadData(foto);
                        //imgList.Add(img);
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine("WARNING");
                    }
                    k++;
                }
                Thread.Sleep(5000);
                Application.ExitThread();   // Stops the thread
            }
        }//end browser_documentCompleted
    }
}